unit Checkers.Loader;

interface

uses
  Classes,
  SysUtils,
  VectorGeometry,
  VectorTypes,
  GLScene,
  GLMaterial,
  GLFileOBJ,
  GLVectorFileObjects,
  GLSCrossXML,
  Checkers.Utils;

type
  TCheckerModel = record
  public
    ID: Integer;
    Model: TGLFreeForm;
    Color: TVector;
    Offset: TVector4f;
    Scale: TVector2f;
  end;

  TModels = Array[0..3] of TCheckerModel;
  TCheckersLoader = class(TComponent)
  private
    FModels: TModels;
    procedure ParseChecker(const AChecker: GLSXMLNode);
    function GetModels: TModels;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Load(const APath: String);
    property Models: TModels read GetModels;
  end;

function MakeModel(const AModel: TGLFreeForm; const AColor: TVector): TCheckerModel;

implementation

function MakeModel(const AModel: TGLFreeForm; const AColor: TVector): TCheckerModel;
begin
  Result.Model := AModel;
  Result.Color := AColor;
end;

{ TCheckersLoader }

constructor TCheckersLoader.Create(AOwner: TComponent);
begin
  inherited;
end;

function TCheckersLoader.GetModels: TModels;
begin
  Result := FModels;
end;

procedure TCheckersLoader.Load(const APath: String);
var
  vSkinsXML: GLSXMLDocument;
  vRoot: GLSXMLNode;
  vCheckers: GLSXMLNode;
  i: Integer;
  vModel: TCheckerModel;
begin
  if not FileExists(APath) then
    raise Exception.Create('Settings file "' + APath + '" is not exist');
  vSkinsXML := GLSNewXMLDocument();
  vSkinsXML.LoadFromFile(APath);
  vRoot := vSkinsXML.DocumentElement;
  if not FindXMLNode(vRoot, 'Checkers', vCheckers) then
    raise Exception.Create('Checkers node in "' + APath + '" is not exist');
  for i := 0 to vCheckers.ChildNodes.Count - 1 do
  begin
    ParseChecker(vCheckers.ChildNodes.Get(i));
  end;
end;

procedure TCheckersLoader.ParseChecker(const AChecker: GLSXMLNode);
var
  vCurrentString: String;
  vModel: TGLFreeForm;
  vID: Integer;
  vColor: TVector;
  vScale: TVector2f;
  vOffset: TVector3f;
begin
  GetXMLAttribute(AChecker, 'id', vCurrentString);
  vID := StrToInt(vCurrentString);
  vModel := TGLFreeForm.Create(Self);
  vModel.Name := 'checker_' + vCurrentString;
  vModel.Visible := False;
  GetXMLAttribute(AChecker, 'file', vCurrentString);
  vModel.LoadFromFile(vCurrentString);
  GetXMLAttribute(AChecker, 'color', vCurrentString);
  vColor := VectorMake(StringToVector3f(vCurrentString), 1.0);
  GetXMLAttribute(AChecker, 'scale', vCurrentString);
  StrToVec(vCurrentString, vScale);
  FModels[vID] := MakeModel(vModel, vColor);
  FModels[vID].ID := vID;
  FModels[vID].Model.Scale.X := vScale[0];
  FModels[vID].Model.Scale.Z := vScale[0];
  FModels[vID].Model.Scale.Y := vScale[1];
  GetXMLAttribute(AChecker, 'shift', vCurrentString);
  StrToVec(vCurrentString, vOffset);
  FModels[vID].Offset := VectorMake(vOffset);
end;

destructor TCheckersLoader.Destroy;
var
  i: Integer;
begin
  for i := 0 to Length(FModels) - 1 do
    if Assigned(FModels[i].Model) then
      FModels[i].Model.Free;
  inherited;
end;

end.
